package nl.rug.ai.believer.model;

/**
 * This class is the main (public) interface for any classes from other packages to communicate
 * with the Believer package. This package will throw RuntimeExceptions in case of illegal states
 * or unexpected problems, but should not raise any exceptions when used with valid input.
 * It is both making use of the Singleton design pattern to ensure only one instance of the program
 * runs at the same time, and the Facade pattern to provide access to this program through one class.
 * @author S1849700
 *
 */
public class Core {

	private static Core core = null;
	private State state = new State();
	
	/**
	 * Singleton, private constructor
	 */
	private Core(){
		
	}
	
	/**
	 * Singleton, this method ensures there is at least (and at most) 1 core and returns that.
	 * @return The requested instance.
	 */
	public static Core getCore() {
		if (core == null) {
			core = new Core();
		}
		return core;
	}
	
	/**
	 * This method reads a file, and loads all data from that file into the core. (Clears all 
	 * existing data first.)
	 * @param file the name of the file to read.
	 * @return true if the file was read successfully, false if not.
	 */
	public boolean readFile(String file) {
		BelieverFileReader reader = new BelieverFileReader();
		return reader.read(file, state);
	}
	
	/**
	 * This method determines if a formula is true or not in our current model. 
	 * @param statement The statement to be evaluated.
	 * @return The result of the evaluation.
	 */
	public boolean evaluate(String formula) {
		Evaluator eval = new Evaluator(state.clone());
		return eval.evaluate(formula);
	}
	
	/**
	 * This method generates a textual list of all worlds (1 name per line) that exist in this core.
	 * @return The list of Worlds
	 */
	public String listWorlds() {
		return state.listWorlds();
	}
	
	/**
	 * This method creates a list of all relations that currently exist in this core, per line there will
	 * be "agent name", "from world name" and "to world name".
	 * @return The list of Relations
	 */
	public String listRelations() {
		return state.listRelations();
	}
	
	/**
	 * This method makes a list of all agents that currently exist in this core (1 name per line).
	 * @return The list of Agents
	 */
	public String listAgents() {
		return state.listAgents();
	}
	
	/**
	 * This method returns a list of all equivalence classes (listing agent + worlds for each class).
	 * @return The list of Equivalence Classes
	 */
	public String listEquivalenceClasses() {
		return state.listEquivalenceClasses();
	}
	
	/**
	 * This method allows you to set "verbose" to either true or false, if true, debug statements may show.
	 * @param verbose the desired value of verbose.
	 */
	public void setVerbose(boolean verbose) {
		Util.verbose = verbose;
	}
	
	/**
	 * This method tells the Util class it should try to reload its config file.
	 */
	public void reloadConfig() {
		Util.loadConfig();
	}
}
